package mn.idax.exchange.otc.service.impl;

import mn.idax.exchange.otc.constant.CommonConstant;
import mn.idax.exchange.otc.domain.UserListResultDTO;
import mn.idax.exchange.otc.entity.*;
import mn.idax.exchange.otc.enums.CommentTypeEnum;
import mn.idax.exchange.otc.enums.OTCUserEnum;
import mn.idax.exchange.otc.enums.UserEnum;
import mn.idax.exchange.otc.enums.response.OrderResponseEnum;
import mn.idax.exchange.otc.enums.response.UserResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.mapper.OTCUserGroupMapper;
import mn.idax.exchange.otc.mapper.OTCUserMapper;
import mn.idax.exchange.otc.service.FileUrlService;
import mn.idax.exchange.otc.service.OTCUserService;
import mn.idax.exchange.otc.service.UserService;
import mn.idax.exchange.otc.util.DateUtils;
import mn.idax.exchange.otc.util.LogUtils;
import mn.idax.exchange.otc.util.NickNameUtils;
import mn.idax.exchange.otc.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Create by jack_huang on 2018/8/9
 */
@Service
public class OTCUserServiceImpl implements OTCUserService {

    @Autowired
    private OTCUserMapper otcUserMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private OTCUserGroupMapper otcUserGroupMapper;

    @Autowired
    private FileUrlService fileUrlService;



    @Override
    public Boolean addUserGoodRate(OTCComment otcComment) {

        LogUtils.info(this.getClass(), "预期更新用户好评条数一条");


        OTCUserExample example = new OTCUserExample();
        example.createCriteria().andUseridEqualTo(otcComment.getBecommentuserid());


        List<OTCUser> otcUsers = otcUserMapper.selectByExample(example);
        if (otcUsers.isEmpty()){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        OTCUser otcUser = otcUsers.get(0);

        Integer goodnumber = Optional.ofNullable(otcUser.getGoodnumber()).orElse(0);
        if (otcComment.getCommenttype().equals(CommentTypeEnum.COMMENT_GOOD.getCode())){
            goodnumber += 1;
        }
        Integer badnumber = Optional.ofNullable(otcUser.getBadnumber()).orElse(0);
        if (otcComment.getCommenttype().equals(CommentTypeEnum.COMMENT_NEGATIVE.getCode()) ){
            badnumber +=  1;
        }
        Integer normalnumber = Optional.ofNullable(otcUser.getNormalnumber()).orElse(0);
        if (otcComment.getCommenttype().equals(CommentTypeEnum.COMMENT_MEDIUM.getCode()) ){
            normalnumber +=  1;
        }
        int totalNumber = goodnumber + badnumber;

        //好评率保留了四位小数 四舍五入

        BigDecimal goodRate = totalNumber == 0
                ? new BigDecimal(0)
                : new BigDecimal(goodnumber).divide(new BigDecimal(totalNumber), CommonConstant.COMMENTDECIMAL,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100));

        int updateFlag = otcUserMapper.updateOTCUser(new OTCUserGoodRate(otcUser.getUserid(),goodRate,goodnumber,badnumber,
                normalnumber,otcUser.getRowversion(),DateUtils.getUTCNow()));

        if (updateFlag < 1){
            return false;
        }

        return true;
    }

    @Override
    public Boolean updateUserGoodRate(OTCComment oldComment,OTCComment newComment) {

        LogUtils.info(this.getClass(), "预期更新用户好评条数一条");


        OTCUserExample example = new OTCUserExample();
        example.createCriteria().andUseridEqualTo(newComment.getBecommentuserid());


        List<OTCUser> otcUsers = otcUserMapper.selectByExample(example);
        if (otcUsers.isEmpty()){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        OTCUser otcUser = otcUsers.get(0);

        Integer goodnumber = Optional.ofNullable(otcUser.getGoodnumber()).orElse(0);
        Integer badnumber = Optional.ofNullable(otcUser.getBadnumber()).orElse(0);
        Integer normalnumber = Optional.ofNullable(otcUser.getNormalnumber()).orElse(0);
        // 原评价等级为差评，差评应减1，下同
        if (newComment.getCommenttype().equals(CommentTypeEnum.COMMENT_GOOD.getCode())){
            goodnumber += 1;
            if (oldComment.getCommenttype().equals(CommentTypeEnum.COMMENT_NEGATIVE.getCode())){
                badnumber -= 1;
            } else {
                normalnumber -= 1;
            }
        }else if (newComment.getCommenttype().equals(CommentTypeEnum.COMMENT_NEGATIVE.getCode()) ){
            badnumber += 1;
            if (oldComment.getCommenttype().equals(CommentTypeEnum.COMMENT_GOOD.getCode())){
                goodnumber -= 1;
            } else {
                normalnumber -= 1;
            }
        }else if (newComment.getCommenttype().equals(CommentTypeEnum.COMMENT_MEDIUM.getCode()) ){
            normalnumber += 1;
            if (oldComment.getCommenttype().equals(CommentTypeEnum.COMMENT_GOOD.getCode())){
                goodnumber -= 1;
            }else if (oldComment.getCommenttype().equals(CommentTypeEnum.COMMENT_NEGATIVE.getCode())){
                badnumber -= 1;
            }
        }
        int totalNumber = badnumber + goodnumber;

        //好评率保留了两位小数 四舍五入

        BigDecimal goodRate = totalNumber == 0
                ? new BigDecimal(0)
                : new BigDecimal(goodnumber).divide(new BigDecimal(totalNumber),CommonConstant.COMMENTDECIMAL,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100));

        int updateFlag = otcUserMapper.updateOTCUser(new OTCUserGoodRate(otcUser.getUserid(),goodRate,goodnumber,badnumber,
                normalnumber,otcUser.getRowversion(),DateUtils.getUTCNow()));

        if (updateFlag < 1){
            return false;
        }

        return true;
    }


    //获取信任名单或者黑名单
    @Override
    public UserListResultDTO getUserGroupMembers(UserPageParamsDTO userPageParamsDTO) {

        //list
        List<UserPageListDTO> goodList = otcUserMapper.getUserGroupList(userPageParamsDTO);

        //查询结果为空 返回空对象
        if (goodList.isEmpty()){
            List<UserTrustOrBlackDTO> userPageLisetDTOS = new ArrayList<>();
            return new UserListResultDTO(userPageLisetDTOS,0);
        }
        List<UserTrustOrBlackDTO> userTrustOrBlack = makeUserPageList(goodList);
        //total
        Integer total = otcUserMapper.getUserGroupTotal(userPageParamsDTO);

        return new UserListResultDTO(userTrustOrBlack,total);
    }


    //封装查询结果
    private List<UserTrustOrBlackDTO> makeUserPageList(List<UserPageListDTO> pageList) {
        List<UserTrustOrBlackDTO> userPageList = new ArrayList<>();
        for (UserPageListDTO userPageListDTO : pageList) {
            UserTrustOrBlackDTO userTrustOrBlack = new UserTrustOrBlackDTO();
            userTrustOrBlack.setUniqueKey(userPageListDTO.getUniqueKey());
            userTrustOrBlack.setNickName(NickNameUtils.concatNickName(userPageListDTO.getNickName(),userPageListDTO.getEmail()));
            userTrustOrBlack.setTradeNumber(userPageListDTO.getTradeNumber());
            userTrustOrBlack.setGoodNumber(userPageListDTO.getGoodNumber());
            userTrustOrBlack.setBadNumber(userPageListDTO.getBadNumber());
            userTrustOrBlack.setGoodRate(userPageListDTO.getGoodRate());
            userTrustOrBlack.setIconurl(fileUrlService.dealFileUrlAddress(userPageListDTO.getIconurl()));
            userPageList.add(userTrustOrBlack);
        }
        return userPageList;
    }


    //添加信任名单
    @Override
    public Boolean addGoodList(Integer beControlUserId, Integer userId) {
        //通过传进来的userid 查询是否有这个用户
        User user = userService.getUserById(beControlUserId);
        if (user==null){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }

        //查询是否已经添加进白名单
        OTCUserGroupExample example = new OTCUserGroupExample();
        example.createCriteria().andTypeEqualTo(UserEnum.trust_List.getCode()).andCreatorEqualTo(userId).andUseridEqualTo(beControlUserId);
        List<OTCUserGroup> otcUserGroups = otcUserGroupMapper.selectByExample(example);
        if (otcUserGroups.size() != 0){
            throw new IdaxException(UserResponseEnum.USER_ADDEDGOODLIST.getRespCode());
        }

        //添加之前先查询是否已在黑名单中,已有?不再添加进白名单,type =2 黑名单
        List<UserTrustOrBlackDTO> blackList = getUserGroupMembers(new UserPageParamsDTO(userId, UserEnum.black_List.getCode(), 0, 14)).getData();
        if( blackList.stream().anyMatch(s ->s.getUniqueKey().equals(getOTCUserByUserId(beControlUserId).getUniquekey()))){
            throw new IdaxException(UserResponseEnum.USER_TRUSTORBLACK.getRespCode());
        }


        //插入数据
        OTCUserGroup otcUserGroup = new OTCUserGroup();
        otcUserGroup.setType(UserEnum.trust_List.getCode());
        otcUserGroup.setUserid(user.getId());
        otcUserGroup.setCreator(userId);
        otcUserGroup.setCreatetime(DateUtils.getUTCNow());
        otcUserGroup.setUpdatetime(otcUserGroup.getCreatetime());
        return otcUserGroupMapper.insertSelective(otcUserGroup) > 0;
    }

    //移除信任名单或者黑名单
    @Override
    public Boolean removeTrustOrBlack(Integer beControlUserId, Integer userId) {
        //通过id 查询是否有这个用户
        User user = userService.getUserById(beControlUserId);
        if (user==null){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        OTCUserGroupExample example = new OTCUserGroupExample();
        example.createCriteria().andUseridEqualTo(user.getId()).andCreatorEqualTo(userId);
        return  otcUserGroupMapper.deleteByExample(example) > 0;
    }

    //添加黑名单
    @Override
    public Boolean addBlackList(Integer beControlUserId, Integer userId) {
        //通过id 查询是否有这个用户
        User user = userService.getUserById(beControlUserId);
        if (user==null){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }

        //查询是否已经添加进黑名单
        OTCUserGroupExample example = new OTCUserGroupExample();
        example.createCriteria().andTypeEqualTo(UserEnum.black_List.getCode()).andCreatorEqualTo(userId).andUseridEqualTo(beControlUserId);
        List<OTCUserGroup> otcUserGroups = otcUserGroupMapper.selectByExample(example);
        if (otcUserGroups.size() != 0){
            throw new IdaxException(UserResponseEnum.USER_ADDEDBLACKLIST.getRespCode());
        }

        //添加之前先查询是否已在白名单中,已有?不再添加进白名单,type =1 白名单
        List<UserTrustOrBlackDTO> blackList = getUserGroupMembers(new UserPageParamsDTO(userId, UserEnum.trust_List.getCode(), 0, 14)).getData();
        if(  blackList.stream().anyMatch(s ->s.getUniqueKey().equals(getOTCUserByUserId(beControlUserId).getUniquekey()))){
            throw new IdaxException(UserResponseEnum.USER_TRUSTORBLACK.getRespCode());
        }

        //插入数据
        OTCUserGroup otcUserGroup = new OTCUserGroup();
        otcUserGroup.setType(UserEnum.black_List.getCode());
        otcUserGroup.setUserid(user.getId());
        otcUserGroup.setCreator(userId);
        otcUserGroup.setCreatetime(DateUtils.getUTCNow());
        otcUserGroup.setUpdatetime(otcUserGroup.getCreatetime());
        return otcUserGroupMapper.insertSelective(otcUserGroup) > 0;
    }

    //获取otcuser信息
    @Override
    public OTCUser getOTCUserByUserId(Integer userId) {
        OTCUserExample example = new OTCUserExample();
        example.createCriteria().andUseridEqualTo(userId);
        //通过nickName 查询是否有这个用户
        List<OTCUser> users = otcUserMapper.selectByExampleWithBLOBs(example);
        return users.isEmpty() ? null : users.get(0);
    }

    @Override
    public int updateTradenumber(OTCUser updateUser,Integer oldTradenumber){
        OTCUserExample example = new OTCUserExample();
        example.createCriteria()
                .andUseridEqualTo(updateUser.getId())
                .andTradenumberEqualTo(oldTradenumber);
        updateUser.setUpdatetime(DateUtils.getUTCNow());
        return this.otcUserMapper.updateByExample(updateUser,example);
    }

    @Override
    public int updateTradenumberAndTurnover(Integer userId,BigDecimal amount){
        OTCUser baseUser = this.getOTCUserByUserId(userId);

        OTCUserExample example = new OTCUserExample();
        example.createCriteria()
                .andUseridEqualTo(userId)
                .andTradenumberEqualTo(baseUser.getTradenumber())
                .andHistoryturnoverEqualTo(baseUser.getHistoryturnover())
                .andRowVersionEqualTo(baseUser.getRowversion());

        OTCUser updateUser = new OTCUser();
        updateUser.setTradenumber(baseUser.getTradenumber() + BigDecimal.ONE.intValue());
        updateUser.setHistoryturnover(baseUser.getHistoryturnover().add(amount));
        updateUser.setUpdatetime(DateUtils.getUTCNow());

        return this.otcUserMapper.updateByExampleSelective(updateUser,example);
    }

    @Override
    public boolean updateTradenumberBySellerAndBuyer(Integer sellerId, Integer buyerId){
        OTCUser seller = this.getOTCUserByUserId(sellerId);
        if (seller == null) {
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        OTCUser buyer = this.getOTCUserByUserId(buyerId);
        if (buyer == null) {
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        int oldTradeNumber = seller.getTradenumber();
        seller.setTradenumber(oldTradeNumber + BigDecimal.ONE.intValue());
        int updateSellerRow = this.updateTradenumber(seller,oldTradeNumber);
        if (updateSellerRow <= BigDecimal.ZERO.intValue()){
            throw new IdaxException(OrderResponseEnum.SEND_UPDATEORDERSTATE.getRespCode());
        }

        oldTradeNumber = seller.getTradenumber();
        seller.setTradenumber(oldTradeNumber + BigDecimal.ONE.intValue());
        int updateBuyerRow = this.updateTradenumber(buyer,oldTradeNumber);
        if (updateBuyerRow <= BigDecimal.ZERO.intValue()){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }

        return true;
    }

    @Override
    public boolean updateTransactionInfoBySellerAndBuyer(Integer sellerId,Integer buyerId,BigDecimal amount){
        // 修改交易量和成交额
        int updateSellerRow = this.updateTradenumberAndTurnover(sellerId,amount);
        if (updateSellerRow <= BigDecimal.ZERO.intValue()){
            throw new IdaxException(OrderResponseEnum.UPDATE_ORDERSTATEFAIL.getRespCode());
        }

//        Map<String,Object> conditionMap = new HashMap<>();
//        otcUserMapper.updateTradenumberAndTurnover();

        int updateBuyerRow = this.updateTradenumberAndTurnover(buyerId,amount);
        if (updateBuyerRow <= BigDecimal.ZERO.intValue()){
            throw new IdaxException(OrderResponseEnum.UPDATE_ORDERSTATEFAIL.getRespCode());
        }

        return true;
    }

    //当前用户收录的信任名单数和黑名单数
    @Override
    public UserCollectionUsersDTO getUserCollectionUsers(Integer userId) {

        int trustList = otcUserMapper.getUserCollectionTrustUser(userId);
        int distrustList = otcUserMapper.getUserCollectionDistrustUser(userId);
        return new UserCollectionUsersDTO(trustList,distrustList);
    }

    @Override
    public UserGoodNumAndBadNum getUserGoodNumAndBadNum(Integer userId) {
        OTCUser otcUser = getOTCUserByUserId(userId);
        if (otcUser == null){
            throw new IdaxException(UserResponseEnum.USER_ISNOTEXIST.getRespCode());
        }
        return new UserGoodNumAndBadNum(otcUser.getGoodnumber(),otcUser.getBadnumber());
    }


    //uniqueKey get user
    @Override
    public OTCUser getOtcUserByUniqueKey(String uniquekey) {
        OTCUserExample example = new OTCUserExample();
        example.createCriteria().andUniquekeyEqualTo(uniquekey);
        //通过nickName 查询是否有这个用户
        List<OTCUser> users = otcUserMapper.selectByExampleWithBLOBs(example);
        return users.isEmpty() ? null : users.get(0);
    }

    @Override
	public OTCUserADSummaryDTO selectByUserId(Integer userId) {
    	OTCUserADSummaryDTO otcUserADSummaryDTO = otcUserMapper.getSummaryByUserId(userId);
        otcUserADSummaryDTO.setNickName(NickNameUtils.concatNickName(otcUserADSummaryDTO.getNickName(),otcUserADSummaryDTO.getEmail()));
    	//查询该用户的信任人数
    	otcUserADSummaryDTO.setTrustNumber(otcUserGroupMapper.countTrustGroupTotalByUserId(userId));
    	//最后登录时间
    	otcUserADSummaryDTO.setLastLoginTime(getLastLogintime(userId));
    	otcUserADSummaryDTO.setIconurl(fileUrlService.dealFileUrlAddress(otcUserADSummaryDTO.getIconurl()));
    	return otcUserADSummaryDTO;
	}

    @Override
    public boolean insertSelective(OTCUser otcUser){
        int changeRow = this.otcUserMapper.insertSelective(otcUser);
        if (changeRow == 1){
            return true;
        }
        return false;
    }

	@Override
	public OTCUser getOTCUserByUniqueKey(String uniquekey) {
		return otcUserMapper.getOTCUserByUniqueKey(uniquekey);
	}

	@Override
    public boolean updateIcon(int userId, String icon){

        icon = fileUrlService.subFilePath(icon);

        OTCUser otcUser = this.getOTCUserByUserId(userId);

        OTCUserExample example = new OTCUserExample();
        example.createCriteria()
                .andUseridEqualTo(userId)
                .andRowVersionEqualTo(otcUser.getRowversion());

        OTCUser updateUser = new OTCUser();
        updateUser.setIconurl(icon);

        //通过nickName 查询是否有这个用户
        int changeRow = otcUserMapper.updateByExampleSelective(updateUser,example);
        if (changeRow > 0){
            return true;
        }
        return false;
    }

    @Override
    public OTCUserADSummaryDTO getSummaryByUserId(Integer userId) {
        OTCUserADSummaryDTO otcUserADSummaryDTO = otcUserMapper.getSummaryByUserId(userId);
        otcUserADSummaryDTO.setNickName(NickNameUtils.concatNickName(otcUserADSummaryDTO.getNickName(),otcUserADSummaryDTO.getEmail()));
        otcUserADSummaryDTO.setLastLoginTime(getLastLogintime(userId));
        otcUserADSummaryDTO.setIconurl(fileUrlService.dealFileUrlAddress(otcUserADSummaryDTO.getIconurl()));
        return otcUserADSummaryDTO;
    }

    //获取订单详情的user信息
    @Override
    public UserInfoResultDTO getUserInfo(Integer userId) {
        return otcUserMapper.getUserInfo(userId);
    }


    //更改isupdate字段为true，已修改过昵称
    @Override
    public int updateIsUpdated(Integer userId,OTCUser otcUser) {

//
//        OTCUserExample example = new OTCUserExample();
//        example.createCriteria().andIdEqualTo(otcUser.getId());
//        OTCUser updateOtcUser = new OTCUser();
//        updateOtcUser.setIsupdated(true);
//        return otcUserMapper.updateByExampleSelective(updateOtcUser,example);
        return otcUserMapper.updateIsUpdatedTrue(userId);
    }

    @Override
    public int syncOtcUser() {
        return this.otcUserMapper.syncOtcUser();
    }

    /**
     * 获取用户最后登录时间
     * @param userid
     * @return
     */
    @Override
    public String getLastLogintime(Integer userid) {
        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(otcUserMapper.getLastLogintime(userid));
    }

    @Override
    public String getUserIconUrl(Integer userid) {
        return otcUserMapper.getUserIconUrl(userid);
    }

    @Override
    public void updateUserGoodRate(Integer userid) {
        UserGoodNumAndBadNum userGoodNumAndBadNum = getUserGoodNumAndBadNum(userid);

        OTCUser otcUser = new OTCUser();
        otcUser.setGoodnumber(userGoodNumAndBadNum.getGoodNumber() + 1);

        Integer totalNumber = otcUser.getGoodnumber() + userGoodNumAndBadNum.getBadNumber();
        BigDecimal goodRate = new BigDecimal(otcUser.getGoodnumber()).divide(new BigDecimal(totalNumber), CommonConstant.COMMENTDECIMAL,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100));

        otcUser.setGoodrate(goodRate);
        OTCUserExample otcUserExample = new OTCUserExample();
        otcUserExample.createCriteria()
                .andUseridEqualTo(userid);

        otcUserMapper.updateByExampleSelective(otcUser, otcUserExample);
    }

}
